#ifndef MAINDIALOG_H
#define MAINDIALOG_H

#include <BMenu>
#include <BButton>
#include <BCheckBox>
#include <BSlider>
#include <BTableWidget>
#include <BTreeWidget>
#include <BRealSpinBox>
#include <BViewer>
#include <BCamera>
#include <BScene>
#include <BImage>
#include <BGridLayout>
#include <BMainWindow>

#include "panels/CameraPanel.h"

#include "FileDialog.h"
#include "OrganizeDialog.h"
#include "ModifyDialog.h"
#include "PropertyBoard.h"
#include "MyHandler.h"

using namespace BWE;

class MainWindow : public BMainWindow
{
	BOBJECT(MainWindow)
public:
	MainWindow();
	~MainWindow();

	bool openFile(const BString& fileName);

protected:
	void initMenus();
	void freshItemMenu();

	BMenu* createMenu(const BString& text, const BString& name);
	BAction* createAction(const BString& text, const BString& name, BMenu* menu = 0);
	BButton* createButton(const BString& text, const BString& name);

	const char* primName(Primitive prim);
	BString findValidName(const BScene* scene, const BString& name);
	BString findValidName(const BGroup* group, const BString& name);
	BString findValidName(const BNode* node, const BString& name);
	BIcon* typedIcon(const BObject* object);
	BObject* copyObject(const BObject* object);
	BPickHit* insertObject(BPickHit* hit, BObject* object);
	void transform(BGroup* group, const BVector& origin, const BQuater& quater);
	void collapse(BGroup* group);

	void freshMenuIcons(BMenu* menu);
	BTreeItem* createTreeItem(BScene* scene);
	BTreeItem* createTreeItem(BGroup* group);
	BTreeItem* createTreeItem(BNode* node);
	BTreeItem* createTreeItem(BShape* shape);
	BTreeItem* createTreeItem(BRestraint* restraint);
	void removeTreeItem(BTreeItem* item);

protected:
	void slotOpenButtonClicked();
	void slotSaveButtonClicked();

	void slotImportButtonClicked();
	void slotExportButtonClicked();
	void slotResetButtonClicked();
	void slotmodifyButtonClicked();

	void slotUndoButtonClicked(BObject* object, const BValue& value);
	void slotRedoButtonClicked(BObject* object, const BValue& value);
	void slotSelectButtonClicked();
	void slotMoveButtonClicked();
	void slotRotateButtonClicked();
	void slotScaleButtonClicked();

	void slotCreateGroupActionTriggered(BObject* object, const BValue& value);
	void slotCreateNodeActionTriggered(BObject* object, const BValue& value);
	void slotCreateShapeActionTriggered(BObject* object, const BValue& value);
	void slotOrganizeMenuTriggered(BObject* object, const BValue& value);
	void slotConvertMenuTriggered(BObject* object, const BValue& value);
	void slotCopyActionTriggered(BObject* object, const BValue& value);
	void slotCutActionTriggered(BObject* object, const BValue& value);
	void slotPasteActionTriggered(BObject* object, const BValue& value);
	void slotRenameActionTriggered(BObject* object, const BValue& value);
	void slotRemoveActionTriggered(BObject* object, const BValue& value);
	void slotExpandActionTriggered(BObject* object, const BValue& value);
	void slotShrinkActionTriggered(BObject* object, const BValue& value);

	void slotNameEditFocused(BObject* object, const BValue& value);
	void slotClearColorCheckBoxToggled(BObject* object, const BValue& value);
	void slotClearColorButtonClicked(BObject* object, const BValue& value);

	void slotLightingChecked();
	void slotFrameChecked();
	void slotShowNormalsBoxToggled(BObject* object, const BValue& value);
	void slotNormalsButtonGroupClicked(BObject* object, const BValue& value);
	void slotNormalLengthEdited();
	void slotGridLineVisibleChecked(BObject* object, const BValue& value);
	void slotGrdiSizeEditFinished(BObject* object, const BValue& value);
	void slotGridSegmentEditFinished(BObject* object, const BValue& value);
	void slotGridColorButtonClicked();
	void slotResetOriginMenuTriggered(BObject* object, const BValue& value);

	void slotBaseAxisBoxChecked(BObject* object, const BValue& value);
	void slotAxisColorButtonClicked(BButton* button, const BValue& value);

	void slotTreeItemClicked(BObject* object, const BValue& value);
	void slotTreeRightClicked(BObject* object, const BValue& value);
	void slotViewerRightClicked(BObject* object, const BValue& value);
	void slotViewerDragDropped(BObject* object, const BValue& value);

	void slotApplyOpera(BObject* object, const BValue& value);
	void slotCameraFocus(BObject* object, const BValue& value);
	void slotTargetSelected(BObject* object, const BValue& value);
	void slotDeleteTarget(BObject* object, const BValue& value);
	void slotFocusObject(BObject* object, const BValue& value);
	void slotEditMaterial(BObject* object, const BValue& value);
	void slotMatrixChanged(BObject* object, const BValue& value);

	void slotSceneInserted(BObject* object, const BValue& value);
	void slotSceneRemoved(BObject* object, const BValue& value);
	void slotNodeRenamed(BObject* object, const BValue& value);

	void slotDrawCapsuleButtonToggled(BObject* object, const BValue& value);
	void slotDrawConeButtonToggled(BObject* object, const BValue& value);
	void slotDrawCubeButtonToggled(BObject* object, const BValue& value);
	void slotDrawCylinderButtonToggled(BObject* object, const BValue& value);
	void slotDrawSphereButtonToggled(BObject* object, const BValue& value);
	void slotDrawGeoSphereButtonToggled(BObject* object, const BValue& value);
	void slotDrawTubeButtonToggled(BObject* object, const BValue& value);
	void slotDrawTorusButtonToggled(BObject* object, const BValue& value);
	void slotDrawBillboardButtonToggled(BObject* object, const BValue& value);
	void slotDrawTextualButtonToggled(BObject* object, const BValue& value);

	void slotDrawHandlerDetached(BObject* object, const BValue& value);

protected:
	virtual void adjustEvent(const BEvent& event);

	virtual void styleEvent(const BEvent& event);

private:
	BButton*			_openButton;
	BButton*			_saveButton;
	BButton*			_importButton;
	BButton*			_exportButton;
	BButton*			_resetButton;
	BButton*			_viewButton;
	BButton*			_modifyButton;

	BButton*			_undoButton;
	BButton*			_redoButton;
	BButton*			_selectButton;
	BButton*			_moveButton;
	BButton*			_rotateButton;
	BButton*			_scaleButton;
	BButtonGroup*		_modeButtonGroup;

	BCheckBox*			_clearColorCheckBox;
	BGridLayout*		_colorGridLayout;
	BCheckBox*			_frameCheckBox;
	BCheckBox*			_lightingCheckBox;

	BGroupBox*			_normalsGroupBox;
	BSlider*			_normalLengthSlider;
	BGroupBox*			_gridLinesGroupBox;
	BRealSpinBox*		_gridSizeSpinBox;
	BSpinBox*			_gridSegmentSpinBox;
	BButton*			_gridColorButton;
	BGroupBox*			_baseLinesGroupBox;
	BCheckBox*			_baseAxisXCheckBox;
	BCheckBox*			_baseAxisYCheckBox;
	BCheckBox*			_baseAxisZCheckBox;
	BButton*			_axisXColorButton;
	BButton*			_axisYColorButton;
	BButton*			_axisZColorButton;

	BTreeWidget*		_sceneTreeWidget;
	BViewer*			_sceneViewer;
	CameraPanel*		_cameraPanel;
	TransformNote*		_transformNote;
	PropertyBoard*		_propertyBoard;

	BMenu*				_itemMenu;
	BMenuHolder			_createMenu;
	BMenuHolder			_organizeMenu;
	BMenuHolder			_convertMenu;
	BMenuHolder			_resetOriginMenu;
	BActionHolder		_copyAction;
	BActionHolder		_cutAction;
	BActionHolder		_pasteAction;
	BActionHolder		_renameAction;
	BActionHolder		_removeAction;
	BActionHolder		_expandAction;
	BActionHolder		_shrinkAction;

	BButton*			_drawConeButton;
	BButton*			_drawCubeButton;
	BButton*			_drawSphereButton;
	BButton*			_drawGeoSphereButton;
	BButton*			_drawCylinderButton;
	BButton*			_drawCapsuleButton;
	BButton*			_drawTubeButton;
	BButton*			_drawTorusButton;
	BButton*			_drawBillboardButton;
	BButton*			_drawTextualButton;

	BMap<BString, BActionHolder>	_namedActionMap;
	BMap<BString, BMenuHolder>		_menuMap;

	BLineEdit*			_nameEdit;
	BMenu*				_viewerMenu;
	FileDialog*			_fileDialog;
	OrganizeDialog*		_organizeDialog;
	ModifyDialog*		_modifyDialog;

	BCamera*			_camera;
	MyHandler*			_handler;
	BScene*				_scene;
	BString				_fileName;
	BHolder<Target>		_target;
	int					_operaIndex;
	BArray<OperaHolder>	_operaStack;
};

#endif